#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
Debugger for Wumpus game (dog).
"""

from cave import Cave
from knight import Knight, KnightException
from nature import Nature, NatureException

from cmd import Cmd

class Commands(Cmd):
    percepts = None

    def __init__(self):
        try:
            self.percepts = n.init()
            k.add_percepts(self.percepts)
            self.intro = """
Dog - Wumpus cave debugger.
Press TAB for hints. 

Dog is in the entrance of the cave. 
Dog feels: %s""" % (', '.join(self.percepts) if self.percepts else 'Nothing')
        except Exception as e:
            print "Dog died immediately in the entrance of the cave. Choose a better cave next time."
            quit()
        self.__set_prompt()
        Cmd.__init__(self)

    def __set_prompt(self):
        items = []
        if n.r: items.append('A') #add arrow
        if n.g: items.append('G') #add gold
        if not items: items.append('-')
        self.prompt = '[%d : %s] > ' % (k.time, ''.join(items))
    
    def __execute_action(self, a):
        # send and print env
        k.add_action(a)
        print 'After %s ...' % a
        try:
            self.percepts = n.react(a)
            k.add_percepts(self.percepts)
            print '\tdog feels: %s' % (', '.join(self.percepts) if self.percepts else 'Nothing')
        except (KnightException, NatureException) as e:
            print '\tgame is over.'
            print '%s after %d step(s).' % (e[0], e[1])
            quit()
        self.__set_prompt()

    # agent actions
    def do_forward(self,l): 
        """Move forward"""
        self.__execute_action('Forward')
    def do_left(self,l): 
        """Turn 90 degrees left"""
        self.__execute_action('Left')
    def do_right(self,l): 
        """Turn 90 degrees right"""
        self.__execute_action('Right')
    def do_grab(self,l): 
        """Grab item on the floor"""
        self.__execute_action('Grab')
    def do_shoot(self,l): 
        """Shoot an arrow (if still have one)"""
        self.__execute_action('Shoot')
    def do_climb(self,l): 
        """Climb up the room"""
        self.__execute_action('Climb')
    # others
    def do_quit(self, l):
        """Quits the program."""
        quit()
    def do_dump(self, l):
        """Dump current input.idp"""
        print k.genStructere()
    def do_idp(self, l):
        """Dump complete IDP file (commonvoc.idp + theory.idp + input.idp)"""
        print k.getFullIDP()
    def do_out(self, l):
        """Dump last IDP output"""
        print k.dump_output()
    def do_auto(self, l):
        """Call agent to propose move"""
        if k.theory:
            try:
                action = k.runtheory()
                print "Your agent recommends: %s" % action
                print "Used: %fs" % k.idptime
            except KnightException as e:
                print "Your agent panics."
                if 'nil' in e[1]:
                    print 'No models?' 
                print "Use out to see IDP output." 
        else:
            print "No agent given."
    def do_reload(self, l):
        """Reload agent file"""
        global k
        if k.theory:
            k.parseTheory()
            print "Agent reloaded."
        else:
            print "No agent given."
    def preloop(self):
        pass
    def emptyline(self):
        pass

#prompt parsing
import argparse
parser = argparse.ArgumentParser(description='Sniffs in caves inhabited by Wumpus.')
parser.add_argument('agent', type=argparse.FileType('r'), 
                   help='agents theory file', nargs='?')
parser.add_argument('cave', type=file,
                   help='file with cave map')
parser.add_argument('--idp3', dest='idp3', default='./bin/runidp.sh',
                   help='path to runidp script')
args = parser.parse_args()

c = Cave(args.cave.read())
k = Knight(args.agent.name if args.agent else '', args.idp3)
n = Nature(c)

app = Commands()
app.cmdloop()

